package cn.com.generaldata.os.service.impl;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import org.nutz.dao.Cnd;
import org.nutz.dao.Condition;
import org.nutz.dao.Dao;
import org.nutz.dao.impl.sql.SqlTemplate;
import org.nutz.lang.Lang;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.generaldata.jsme_indicator_system.entity.Dustry;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;

/**
 * 国民经济产业分类代码service.
 */
@Service
public class DustryService {

	@Autowired
	private Dao dao;

	@Autowired
	private SqlTemplate sqlTemplate;

	private final Cache<String, Integer> dustryIndexCache = CacheBuilder.newBuilder()
			.expireAfterAccess(1, TimeUnit.DAYS).build();

	/**
	 * 根据年份获取对应的国民经济产业分类代码.
	 * 
	 * @param year
	 * @return
	 */
	public List<Dustry> getDustrys(int year) {
		int lastVersionYear = getLastDustryYear(year);
		List<Dustry> result = Lists.newArrayList();
		if (lastVersionYear != 0) {
			Condition cnd = Cnd.where("year", "=", lastVersionYear).asc("code");
			result = dao.query(Dustry.class, cnd);
		}
		return result;
	}

	/**
	 * 根据年份获取需要计算评估指标的国民经济产业分类代码.
	 * 
	 * @param year
	 * @return
	 */
	public List<Dustry> getEnableDustrys(int year) {
		int lastVersionYear = getLastDustryYear(year);
		List<Dustry> result = Lists.newArrayList();
		if (lastVersionYear != 0) {
			Condition cnd = Cnd.where("year", "=", lastVersionYear).and("enable", "=", 1).asc("code");
			result = dao.query(Dustry.class, cnd);
		}
		return result;
	}

	public int getLastDustryYear(int year) {
		String sql = "SELECT MAX(year) FROM tbl_dustry WHERE year <= @year";
		return sqlTemplate.queryForInt(sql, ImmutableMap.<String, Object> of("year", year));
	}

	/**
	 * 获取国民经济产业分类代码所处的索引.
	 * 
	 * @param dustry
	 * @return
	 */
	public int getDustryIndex(final Dustry dustry) {
		int index = 0;
		try {
			index = dustryIndexCache.get(dustry.getId(), new Callable<Integer>() {
				@Override
				public Integer call() {
					List<Dustry> dustries = getDustrys(dustry.getYear());
					for (int i = 0; i < dustries.size(); i++) {
						Dustry d = dustries.get(i);
						dustryIndexCache.put(d.getId(), i);
					}
					return dustries.indexOf(dustry);
				}
			});
		} catch (ExecutionException e) {
			throw Lang.makeThrow("获取行业分类索引错误,产业分类信息:%s", dustry.toString(), e);
		}

		return index;
	}
}
